문제 설명

프로그래머스 팀에서는 기능 개선 작업을 수행 중입니다. 각 기능은 진도가 100%일 때 서비스에 반영할 수 있습니다.

또, 각 기능의 개발속도는 모두 다르기 때문에 뒤에 있는 기능이 앞에 있는 기능보다 먼저 개발될 수 있고, 이때 뒤에 있는 기능은 앞에 있는 기능이 배포될 때 함께 배포됩니다.

먼저 배포되어야 하는 순서대로 작업의 진도가 적힌 정수 배열 progresses와 각 작업의 개발 속도가 적힌 정수 배열 speeds가 주어질 때 각 배포마다 몇 개의 기능이 배포되는지를 return 하도록 solution 함수를 완성하세요.

제한 사항

  • 작업의 개수(progresses, speeds배열의 길이)는 100개 이하입니다.
  • 작업 진도는 100 미만의 자연수입니다.
  • 작업 속도는 100 이하의 자연수입니다.
  • 배포는 하루에 한 번만 할 수 있으며, 하루의 끝에 이루어진다고 가정합니다. 예를 들어 진도율이 95%인 작업의 개발 속도가 하루에 4%라면 배포는 2일 뒤에 이루어집니다.

입출력 예

progresses speeds return
[93,30,55] [1,30,5] [2,1]

입출력 예 설명

첫 번째 기능은 93% 완료되어 있고 하루에 1%씩 작업이 가능하므로 7일간 작업 후 배포가 가능합니다. 두 번째 기능은 30%가 완료되어 있고 하루에 30%씩 작업이 가능하므로 3일간 작업 후 배포가 가능합니다. 하지만 이전 첫 번째 기능이 아직 완성된 상태가 아니기 때문에 첫 번째 기능이 배포되는 7일째 배포됩니다. 세 번째 기능은 55%가 완료되어 있고 하루에 5%씩 작업이 가능하므로 9일간 작업 후 배포가 가능합니다.

따라서 7일째에 2개의 기능, 9일째에 1개의 기능이 배포됩니다.

나의 풀이

첫 번째 풀이

소스

def solution(progresses, speeds):
    answer = []

    # 작업 큐에 작업이 남아있으면 계속해서 수행
    while len(progresses) > 0:
        # 우선 작업을 수행시킨다.
        for i in range(len(progresses)):
            progresses[i] += speeds[i]

        # 앞에서 부터 작업 완료된 것이 있는지 체크한다. 완료되었으면 작업 큐에서 제거
        work_complete_num = 0
        for j in range(len(progresses)):
            if progresses[0] >= 100:
                work_complete_num += 1
                progresses.pop(0)
            else: # 완료 되지 않았다면 넘긴다.
                break

        # 완료된 작업의 개수가 0보다 크면 anwser에 추가.
        if work_complete_num > 0:
            answer.append(work_complete_num)

    return answer

설명

우선, 이 문제에 대해서 큐로 접근해야 겠다고 생각을 했는데,

progresses와 speeds는 길이가 같기 때문에, 별도의 처리를 하지 않았고

progresses에 있는 작업의 크기를 speeds만큼 계속 키워나가서 첫번째 작업이 완료(100이 넘으면)되었으면 작업성공수를 키우고 큐에서 제거하고, 그 다음 작업이 완료되었는지를 보는 이런식으로 코딩을 구성하였다.

결과

나름 잘 푼것 같았는데 결과는 처참… 30점이였나 그랬다. 일단 더 안보고 리뷰어님에게 리뷰를 요청하였다.

리뷰

리뷰어님 말씀은 일단 코드는 깔끔하게 잘 했다고 하셨는데,

내가 코드 가독성에 엄청엄청 신경을 쓰면서 개발하는걸 알아주셔서 기뻤다.

리뷰어님이 지적한 문제는 progresses에서만 pop을 해서 문제라고 하셨다. speeds도 같이 줄여줘야 됬었는데… ㅠ

어쨌든 이거 외에 잘 풀면 O(n)으로도 풀이가 가능하다고 하셨다.

두 번째 풀이

소스

def solution(progresses, speeds):
    answer = []

    zip_progress_speed = [list(v) for v in zip(progresses, speeds)]

    # 작업 큐에 작업이 남아있으면 계속해서 수행
    while len(zip_progress_speed) > 0:
        # 우선 작업을 수행시킨다.
        for i in range(len(zip_progress_speed)):
            zip_progress_speed[i][0] += zip_progress_speed[i][1]

        # 앞에서 부터 작업 완료된 것이 있는지 체크한다. 완료되었으면 작업 큐에서 제거
        work_complete_num = 0
        try:
            while zip_progress_speed[0][0] >= 100:
                work_complete_num += 1
                zip_progress_speed.pop(0)
        except:  # zip_progress_speed에 아무것도 없으면 패스.
            pass

        # 완료된 작업의 개수가 0보다 크면 anwser에 추가.
        if work_complete_num > 0:
            answer.append(work_complete_num)

    return answer

설명

위 첫번째 풀이에서 progresses와 speeds의 상관관계를 생각 하지 않아서 문제가 발생하여서,

이번에는 아예 zip으로 묶어서 작업을 시켰다.

가독성이 저번보다 떨어진 것 같은데 ㅠㅠ 어쩔 수 없나… dic으로 만들걸 그랬나?

어쨋든 해결!

결과

해결.